約 4,339,099 件
https://w.atwiki.jp/gametips/pages/15.html
更新日時 2013-06-15 23 56 56 (Sat)アクセス数 - OpenGL API リファレンス 概要 OpenGL APIの日本語リファレンスを掲載しています。 索引 B glBindAttribLocation glBindBuffer glBindFragDataLocation glBindVertexArray glBufferData D glDeleteBuffers glDeleteVertexArrays glDisableVertexAttribArray glDrowArrays glDrowElements E glEnableVertexAttribArray G glGenBuffers glGenVertexArrays V glVertexAttribPointer 参考文献 OpenGLに関連するオススメの本や WEB サイトを紹介します. ページ右の画像をクリックすると Amazon で参考文献を購入できます. OpenGL策定委員会, 「OpenGLプログラミングガイド 原著第5版」, ピアソンエデュケーション OpenGLの赤本(Red Book)と呼ばれる定番の参考書の日本語版です。 少し値は張りますがOpenGLの基本的な使い方が丁寧にまとめられています。 初心者の方には敷居が高いかもしれませんがOpenGLを極めるつもりなら必須の教本だと思います。 Mark Segal, Kurt Akeley, Jon Leech, 「OpenGL4.0グラフィックスシステム」, カットシステム OpenGLの仕様書の日本語訳です。個人的には翻訳に違和感を覚えることはありませんでした。 英語が苦手な方は本書をAPIリファレンスの代わりに利用できます。 チュートリアルのような内容は含まれていませんので他の書籍との併用をオススメします。 床井 浩平, 「GLUTによるOpenGL入門」, 工学社 これから OpenGL を初めようとしている方にはこの本がオススメです。 おそらく OpenGL に関する文献の中では最も敷居が低く 3DCG に関する知識が全くなくても理解しやすいです。 少し内容は古いかもしれませんが導入という目的では最高の文献で、私もこの本から OpenGL に入門しました。 床井 浩平, 「GLUTによるOpenGL入門2 テクスチャマッピング」, 工学社 上の「GLUT によるOpenGL入門」の続編です。 前作の内容では物足りなかった方は本書を読むことで 3DCG の表現力が大幅に広がります。 引き続き平易な内容となっており、前作を読破した方であれば難なく理解できると思います。 David Wolff , 「OpenGL 4.0 シェーディング言語 -実例で覚えるGLSLプログラミング-」, ボーンデジタル 最近のゲームに見られるようなリアルな映像をつくりだすにはプログラマブル・シェーダという機能が欠かせません。 床井 浩平さんの「GLUTによるOpenGL入門2 テクスチャマッピング」でもシェーダに関しては少しだけ触れられていますが、書籍の後半で軽く紹介されているだけでいささか物足りない内容ではありますので、本格的に学ぶためにこの本の購入をオススメします。 質問・コメント欄 名前 コメント すべてのコメントを見る
https://w.atwiki.jp/frontiergt/pages/34.html
注意事項 Windowsでコンパイルしたい場合は管理人に直接聞いてください。 Linuxでコンパイルする場合、Ubuntuを使って下さい。 おそらくFedoraとかだと動かないと思います。 Linuxでコンパイルする場合は、synapticで以下をインストールしてください。 ・build-essential ・freeglut3-dev ・libjpeg-dev ・libpng-dev ・ftgl-dev コンパイル方法は、「sh mk.sh」を実行するだけです。 OpenGLテンプレート ver_02.c2 (管理人) OpenGLテンプレート ver_02.c2 こちらにおいておきます →→ ソースファイル ※変更点※ 表示関係のバグ修正 アニメーション関係のバグ修正 マウス操作性改善 キーボードの反応性の改善(←比にならないくらい改善しました) 旧ubuntuでシャットダウンするバグ修正 OpenGLテンプレート ver_01.n2 (管理人) OpenGLテンプレート ver_01.n2 こちらにおいておきます →→ ソースファイル OpenGLテンプレート ver_01.a (管理人) OpenGLテンプレート ver_01.a こちらにおいておきます →→ ソースファイル コメント 名前 コメント
https://w.atwiki.jp/sevenlives/pages/2257.html
iPhone OpenGL Unity
https://w.atwiki.jp/opengl/pages/188.html
GLSLでテクスチャを描画します。 vertex.shader //フラグメントシェーダーに渡す変数 varying vec3 P;//位置ベクトル varying vec3 N;//法線ベクトル void main(void) { P = vec3(gl_ModelViewMatrix * gl_Vertex); N = normalize(gl_NormalMatrix * gl_Normal).xyz; gl_TexCoord[0] = gl_MultiTexCoord0; gl_Position = ftransform(); } flagment.shader //頂点シェーダーから受け取る変数 varying vec3 P;//位置ベクトル varying vec3 N;//法線ベクトル uniform sampler2D sampler; void main(void) { vec3 L = normalize(gl_LightSource[0].position.xyz - P);//光源ベクトル N = normalize(N); vec4 ambient = gl_FrontLightProduct[0].ambient; float dotNL = dot(N, L);//max(0.0, dot(N, L)); vec4 diffuse = gl_FrontLightProduct[0].diffuse * max(0.0, dotNL); vec3 V = normalize(-P); vec3 H = normalize(L + V); float powNH = pow(max(dot(N, H), 0.0), gl_FrontMaterial.shininess); if(dotNL = 0.0) powNH = 0.0; vec4 specular = gl_FrontLightProduct[0].specular * powNH; //テクスチャの色 vec4 texColor = texture2D(sampler, gl_TexCoord[0].st); //GL_MODULATEモード gl_FragColor = (ambient + diffuse) * texColor + specular; } GLSL.h #pragma once #include stdio.h //GLSLクラス class GLSL{ public GLuint ShaderProg; GLuint VertexShader, FragmentShader; void ReadShaderCompile(GLuint Shader, const char *File);//shader fileを読み込みコンパイルする void Link( GLuint Prog );//リンクする void InitGLSL(const char *VertexFile);//GLSLの初期化 void InitGLSL(const char *VertexFile, const char *FragmentFile);//GLSLの初期化 void ON();//シェーダー描画に切り替え void OFF();//シェーダー解除 ~GLSL(); }; void GLSL ReadShaderCompile(GLuint Shader, const char *File){ FILE *fp; char *buf; GLsizei size, len; GLint compiled; fopen_s( fp,File, rb ); if(!fp) printf( ファイルを開くことができません %s\n , File); fseek(fp, 0, SEEK_END); size = ftell(fp); buf = (GLchar *)malloc(size); if (buf == NULL) { printf( メモリが確保できませんでした \n ); } fseek(fp, 0, SEEK_SET); fread(buf, 1, size, fp); glShaderSource(Shader, 1, (const GLchar **) buf, size); free(buf); fclose(fp); glCompileShader(Shader); glGetShaderiv( Shader, GL_COMPILE_STATUS, compiled ); if ( compiled == GL_FALSE ) { printf( コンパイルできませんでした!! %s \n , File); glGetProgramiv( Shader, GL_INFO_LOG_LENGTH, size ); if ( size 0 ) { buf = (char *)malloc(size); glGetShaderInfoLog( Shader, size, len, buf); printf(buf); free(buf); } } } void GLSL Link( GLuint Prog ){ GLsizei size, len; GLint linked; char *infoLog ; glLinkProgram( Prog ); glGetProgramiv( Prog, GL_LINK_STATUS, linked ); if ( linked == GL_FALSE ){ printf( リンクできませんでした!! \n ); glGetProgramiv( Prog, GL_INFO_LOG_LENGTH, size ); if ( size 0 ){ infoLog = (char *)malloc(size); glGetProgramInfoLog( Prog, size, len, infoLog ); printf(infoLog); free(infoLog); } } } void GLSL InitGLSL(const char *VertexFile){ GLenum err = glewInit(); if (err != GLEW_OK) { printf( Error %s\n , glewGetErrorString(err)); } printf( VENDOR= %s \n , glGetString(GL_VENDOR)); printf( GPU= %s \n , glGetString(GL_RENDERER)); printf( OpenGL= %s \n , glGetString(GL_VERSION)); printf( GLSL= %s \n , glGetString(GL_SHADING_LANGUAGE_VERSION)); VertexShader = glCreateShader(GL_VERTEX_SHADER); ReadShaderCompile(VertexShader, VertexFile); ShaderProg = glCreateProgram(); glAttachShader(ShaderProg, VertexShader); glDeleteShader(VertexShader); Link(ShaderProg); } void GLSL InitGLSL(const char *VertexFile, const char *FragmentFile){ GLenum err = glewInit(); if (err != GLEW_OK) { printf( Error %s\n , glewGetErrorString(err)); } printf( VENDOR= %s \n , glGetString(GL_VENDOR)); printf( GPU= %s \n , glGetString(GL_RENDERER)); printf( OpenGL= %s \n , glGetString(GL_VERSION)); printf( GLSL= %s \n , glGetString(GL_SHADING_LANGUAGE_VERSION)); VertexShader = glCreateShader(GL_VERTEX_SHADER); FragmentShader = glCreateShader(GL_FRAGMENT_SHADER); ReadShaderCompile(VertexShader, VertexFile); ReadShaderCompile(FragmentShader, FragmentFile); ShaderProg = glCreateProgram(); glAttachShader(ShaderProg, VertexShader); glAttachShader(ShaderProg, FragmentShader); glDeleteShader(VertexShader); glDeleteShader(FragmentShader); Link(ShaderProg); } void GLSL ON(){ glUseProgram(ShaderProg); } void GLSL OFF(){ glUseProgram(0); } GLSL ~GLSL(){ glDeleteProgram(ShaderProg); } PNG.h #pragma once #include lodepng.h //テクスチャクラス class TEXTURE{ protected LodePNG_Decoder decoder;//デコーダ unsigned char* buffer;//バッファ size_t buffersize, imagesize;//サイズ public TEXTURE(); TEXTURE(const char* FileName);//コンストラクタ void LOAD_PNG(const char* FileName);//PNG読み込み unsigned char* image;//イメージポインタ unsigned int Width,Height;//画像サイズ }; TEXTURE TEXTURE(){ } TEXTURE TEXTURE(const char* FileName){ LOAD_PNG(FileName); } void TEXTURE LOAD_PNG(const char* FileName){ LodePNG_Decoder_init( decoder); //ロード LodePNG_loadFile( buffer, buffersize, FileName); //デコード LodePNG_decode( decoder, image, imagesize, buffer, buffersize); //幅,高さ Width = decoder.infoPng.width;Height = decoder.infoPng.height; } main.cpp #pragma comment(linker, /SUBSYSTEM WINDOWS /ENTRY mainCRTStartup ) #pragma comment(lib, glew32.lib ) #include GL/glew.h #include GL/freeglut/freeglut.h #include GLSL.h #include math.h #include PNG.h #define PAI 3.141592f #define WIDTH 640 #define HEIGHT 480 GLSL glsl; //回転用 float anglex = 0.0f; //ライトの位置 GLfloat lightpos[] = { 10.0f, 15.0f, 0.0f, 1.0f }; float Ambient[] = {1.0f, 1.0f, 1.0f, 1.0f}; float Diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f}; float Specular[]= { 0.4f, 0.4f, 0.4f, 1.0f};//鏡面反射 float AmbientLight[] = { 0.5f, 0.5f, 0.5f, 1.0f}; float DiffuseLight[] = { 0.7f, 0.7f, 0.7f, 1.0f}; float SpecularLight[] = {1.0f, 1.0f, 1.0f, 1.0f};//鏡面光 float lightDiffuse[4] = {1.0f, 1.0f, 1.0f, 1.0f}; //拡散光 float lightSpecular[4] = {1.0f, 1.0f, 1.0f, 1.0f}; //鏡面光 float pos[] = {0.0f, 2.0f, 0.0f};//位置 bool flag = true; //影のマテリアル float shadowDiffuse[] = {0.0f,0.0f,0.0f,0.3f};//影の拡散光 float shadowSpecular[] = {0.0f,0.0f,0.0f,1.0f};//影の鏡面光 GLuint texID; TEXTURE *texture; void drawTexPlate(float size, int nRepeatS, int nRepeatT){//x-y平面 float sz = 0.5f * size; static float p[4][3] = {//z 上方向 { sz,-sz, 0.0}, { sz, sz, 0.0}, {-sz, sz, 0.0}, {-sz,-sz, 0.0} }; float s = (float)nRepeatS; float t = (float)nRepeatT; glEnable(GL_TEXTURE_2D); glBegin(GL_QUADS); glNormal3f(0.0, 0.0, 1.0); //z方向の法線 //テクスチャー座標と頂点番号との対応付け glTexCoord2f(0.0, 0.0); glVertex3fv(p[3]); glTexCoord2f( s , 0.0); glVertex3fv(p[0]); glTexCoord2f( s , t ); glVertex3fv(p[1]); glTexCoord2f(0.0, t ); glVertex3fv(p[2]); glEnd(); glDisable(GL_TEXTURE_2D); } void draw(bool flag){ if(flag){ glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,shadowDiffuse); glMaterialfv(GL_FRONT,GL_SPECULAR,shadowSpecular); }else{ glMaterialfv(GL_FRONT,GL_AMBIENT,Ambient); glMaterialfv(GL_FRONT,GL_DIFFUSE,Diffuse); glMaterialfv(GL_FRONT,GL_SPECULAR,Specular); glMaterialf(GL_FRONT,GL_SHININESS,100); } glPushMatrix(); glTranslatef(pos[0], pos[1], pos[2]); glRotatef( anglex, 1.0f, 0.0f, 0.0f);//x軸回転 //オブジェクト形状 if(!flag){ drawTexPlate(2.0f,1,1); }else{ drawTexPlate(2.0f,1,1); } glPopMatrix(); } void drawFloor(float widthX, float widthZ, int nx, int nz){ int i, j; //Floor1枚当たりの幅 float wX = widthX / (float)nx; float wZ = widthZ / (float)nz; float diffuse[][4] = { { 0.9f, 0.9f, 0.9f, 1.0f}, { 0.1f, 0.1f, 0.1f, 1.0f} }; float ambient[] = { 0.5f, 0.5f, 0.5f, 1.0f}; float specular[]= { 0.5f, 0.5f, 0.5f, 1.0f}; glMaterialfv(GL_FRONT,GL_AMBIENT,ambient); glMaterialfv(GL_FRONT,GL_SPECULAR,specular); glMaterialf(GL_FRONT,GL_SHININESS,100); glNormal3d(0.0, 1.0, 0.0); glPushMatrix(); for (j = 0; j nz; j++) { float z1 = -widthZ / 2.0f + wZ * j; float z2 = z1 + wZ; for (i = 0; i nx; i++) { float x1 = -widthX / 2.0f + wX * i; float x2 = x1 + wX; glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse[(i + j) 1]); glBegin(GL_QUADS); glVertex3d(x1, 0.0, z1); glVertex3d(x1, 0.0, z2); glVertex3d(x2, 0.0, z2); glVertex3d(x2, 0.0, z1); glEnd(); } } glPopMatrix(); } void CalcShadowMat(float* mat){ float ex, ey, ez;//光源の方向 float s; //object中心から光源までの距離 float x, y, z; x = lightpos[0] - pos[0]; y = lightpos[1] - pos[1]; z = lightpos[2] - pos[2]; //光源の方向ベクトル s = sqrt(x * x + y * y + z * z); ex = x / s; ey = y / s; ez = z / s; //shadow matrix mat[0] = ey; mat[1] = 0.0f; mat[2] = 0.0f; mat[3] = 0.0f; mat[4] = -ex; mat[5] = 0.0f; mat[6] = -ez; mat[7] = 0.0f; mat[8] = 0.0f; mat[9] = 0.0f; mat[10] = ey; mat[11] = 0.0f; mat[12] = 0.0f; mat[13] = 0.001f * ey; mat[14] = 0.0f; mat[15] = ey; } void drawShadow(){ float mat[16]; glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glDepthMask(GL_FALSE); CalcShadowMat( mat); glPushMatrix(); glMultMatrixf(mat); draw(true); glPopMatrix(); glDepthMask(GL_TRUE); glDisable(GL_BLEND); } void setLight(){ glLightfv(GL_LIGHT0, GL_AMBIENT, AmbientLight); glLightfv(GL_LIGHT0, GL_DIFFUSE, DiffuseLight); glLightfv(GL_LIGHT0, GL_SPECULAR, SpecularLight); glLightfv(GL_LIGHT0, GL_POSITION, lightpos); glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); } void display(void){ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport(0, 0, WIDTH, HEIGHT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); //視野角,アスペクト比(ウィンドウの幅/高さ),描画する範囲(最も近い距離,最も遠い距離) gluPerspective(30.0, (double)WIDTH / (double)HEIGHT, 1.0, 1000.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //視点の設定 gluLookAt(0.0,10.0,-10.0, //カメラの座標 0.0,0.0,0.0, // 注視点の座標 0.0,1.0,0.0); // 画面の上方向を指すベクトル //ライトの設定 setLight(); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, texID); glsl.ON(); GLint samplerLoc = glGetUniformLocation(glsl.ShaderProg, sampler ); glUniform1i(samplerLoc, 1);//GL_TEXTURE1を適用 draw(false); glsl.OFF(); drawFloor(10.0, 10.0, 10, 10); drawShadow(); glutSwapBuffers(); } void idle(void){ glutPostRedisplay(); } void Init(){ glsl.InitGLSL( vertex.shader , flagment.shader ); glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glEnable(GL_NORMALIZE); //テクスチャー glGenTextures(1, texID);//テクスチャオブジェクトの名前付け texture = new TEXTURE( tip.png ); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); //テクスチャオブジェクトの作成 glBindTexture(GL_TEXTURE_2D, texID); //テクスチャの指定 glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,texture- Width,texture- Height,0,GL_RGBA,GL_UNSIGNED_BYTE,texture- image); //テクスチャの繰り返し方法の指定 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);//GL_CLAMP); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);//GL_CLAMP); //テクスチャを拡大・縮小する方法の指定 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);//NEAREST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);//NEAREST); glBindTexture(GL_TEXTURE_2D, 0); } //タイマー void timer(int value){ anglex+=1.0f; glutTimerFunc(100 , timer , 0); } void main(int argc, char *argv[]){ glutInitWindowPosition(100, 100); glutInitWindowSize(WIDTH, HEIGHT); glutInit( argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); glutCreateWindow( テクスチャ ); glutDisplayFunc(display); glutIdleFunc(idle); glutTimerFunc(100 , timer , 0); Init(); glutMainLoop(); return; }
https://w.atwiki.jp/opengl/pages/182.html
平面上に影のように見えるオブジェクトを描画します。 vertex.shader //フラグメントシェーダーに渡す変数 varying vec3 P;//位置ベクトル varying vec3 N;//法線ベクトル void main(void) { P = vec3(gl_ModelViewMatrix * gl_Vertex); N = normalize(gl_NormalMatrix * gl_Normal); gl_Position = ftransform(); } flagment.shader //頂点シェーダーから受け取る変数 varying vec3 P;//位置ベクトル varying vec3 N;//法線ベクトル void main(void) { vec3 L = normalize(gl_LightSource[0].position.xyz - P); N = normalize(N); vec4 ambient = gl_FrontLightProduct[0].ambient; float dotNL = dot(N, L); vec4 diffuse = gl_FrontLightProduct[0].diffuse * max(0.0, dotNL); vec3 V = normalize(-P); vec3 H = normalize(L + V); float powNH = pow(max(dot(N, H), 0.0), gl_FrontMaterial.shininess); if(dotNL = 0.0) powNH = 0.0; vec4 specular = gl_FrontLightProduct[0].specular * powNH; //統合 gl_FragColor = ambient + diffuse + specular; } GLSL.h #pragma once #include stdio.h //GLSLクラス class GLSL{ public GLuint ShaderProg; GLuint VertexShader, FragmentShader; void ReadShaderCompile(GLuint Shader, const char *File);//shader fileを読み込みコンパイルする void Link( GLuint Prog );//リンクする void InitGLSL(const char *VertexFile);//GLSLの初期化 void InitGLSL(const char *VertexFile, const char *FragmentFile);//GLSLの初期化 void ON();//シェーダー描画に切り替え void OFF();//シェーダー解除 ~GLSL(); }; void GLSL ReadShaderCompile(GLuint Shader, const char *File){ FILE *fp; char *buf; GLsizei size, len; GLint compiled; fopen_s( fp,File, rb ); if(!fp) printf( ファイルを開くことができません %s\n , File); fseek(fp, 0, SEEK_END); size = ftell(fp); buf = (GLchar *)malloc(size); if (buf == NULL) { printf( メモリが確保できませんでした \n ); } fseek(fp, 0, SEEK_SET); fread(buf, 1, size, fp); glShaderSource(Shader, 1, (const GLchar **) buf, size); free(buf); fclose(fp); glCompileShader(Shader); glGetShaderiv( Shader, GL_COMPILE_STATUS, compiled ); if ( compiled == GL_FALSE ) { printf( コンパイルできませんでした!! %s \n , File); glGetProgramiv( Shader, GL_INFO_LOG_LENGTH, size ); if ( size 0 ) { buf = (char *)malloc(size); glGetShaderInfoLog( Shader, size, len, buf); printf(buf); free(buf); } } } void GLSL Link( GLuint Prog ){ GLsizei size, len; GLint linked; char *infoLog ; glLinkProgram( Prog ); glGetProgramiv( Prog, GL_LINK_STATUS, linked ); if ( linked == GL_FALSE ){ printf( リンクできませんでした!! \n ); glGetProgramiv( Prog, GL_INFO_LOG_LENGTH, size ); if ( size 0 ){ infoLog = (char *)malloc(size); glGetProgramInfoLog( Prog, size, len, infoLog ); printf(infoLog); free(infoLog); } } } void GLSL InitGLSL(const char *VertexFile){ GLenum err = glewInit(); if (err != GLEW_OK) { printf( Error %s\n , glewGetErrorString(err)); } printf( VENDOR= %s \n , glGetString(GL_VENDOR)); printf( GPU= %s \n , glGetString(GL_RENDERER)); printf( OpenGL= %s \n , glGetString(GL_VERSION)); printf( GLSL= %s \n , glGetString(GL_SHADING_LANGUAGE_VERSION)); VertexShader = glCreateShader(GL_VERTEX_SHADER); ReadShaderCompile(VertexShader, VertexFile); ShaderProg = glCreateProgram(); glAttachShader(ShaderProg, VertexShader); glDeleteShader(VertexShader); Link(ShaderProg); } void GLSL InitGLSL(const char *VertexFile, const char *FragmentFile){ GLenum err = glewInit(); if (err != GLEW_OK) { printf( Error %s\n , glewGetErrorString(err)); } printf( VENDOR= %s \n , glGetString(GL_VENDOR)); printf( GPU= %s \n , glGetString(GL_RENDERER)); printf( OpenGL= %s \n , glGetString(GL_VERSION)); printf( GLSL= %s \n , glGetString(GL_SHADING_LANGUAGE_VERSION)); VertexShader = glCreateShader(GL_VERTEX_SHADER); FragmentShader = glCreateShader(GL_FRAGMENT_SHADER); ReadShaderCompile(VertexShader, VertexFile); ReadShaderCompile(FragmentShader, FragmentFile); ShaderProg = glCreateProgram(); glAttachShader(ShaderProg, VertexShader); glAttachShader(ShaderProg, FragmentShader); glDeleteShader(VertexShader); glDeleteShader(FragmentShader); Link(ShaderProg); } void GLSL ON(){ glUseProgram(ShaderProg); } void GLSL OFF(){ glUseProgram(0); } GLSL ~GLSL(){ glDeleteProgram(ShaderProg); } main.cpp #pragma comment(linker, /SUBSYSTEM WINDOWS /ENTRY mainCRTStartup ) #pragma comment(lib, glew32.lib ) #include GL/glew.h #include GL/freeglut/freeglut.h #include GLSL.h #include math.h #define PAI 3.141592f #define WIDTH 640 #define HEIGHT 480 GLSL glsl; //回転用 float anglex = 0.0f; //ライトの位置 GLfloat lightpos[] = { 10.0, 10.0, 10.0, 1.0 }; float Ambient[] = {0.2f, 0.1f, 0.2f, 1.0f}; float Diffuse[] = {0.8f, 0.8f, 0.0f, 1.0f}; float Specular[]= { 0.4f, 0.4f, 0.4f, 1.0f};//鏡面反射 float AmbientLight[] = { 1.0f, 1.0f, 1.0f, 1.0f}; float DiffuseLight[] = { 0.7f, 0.7f, 0.7f, 1.0f}; float SpecularLight[] = {1.0f, 1.0f, 1.0f, 1.0f};//鏡面光 float pos[] = {-0.7f, 1.0f, 0.0f};//位置 bool flag=true; //影のマテリアル float shadowDiffuse[] = {0.0f,0.0f,0.0f,0.3f};//影の拡散光 float shadowSpecular[] = {0.0f,0.0f,0.0f,1.0f};//影の鏡面光 void setLight(){ glLightfv(GL_LIGHT0, GL_AMBIENT, AmbientLight); glLightfv(GL_LIGHT0, GL_DIFFUSE, DiffuseLight); glLightfv(GL_LIGHT0, GL_SPECULAR, SpecularLight); glLightfv(GL_LIGHT0, GL_POSITION, lightpos); } void draw(bool flag){ if(flag) { glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,shadowDiffuse); glMaterialfv(GL_FRONT,GL_SPECULAR,shadowSpecular); }else{ glMaterialfv(GL_FRONT,GL_AMBIENT,Ambient); glMaterialfv(GL_FRONT,GL_DIFFUSE,Diffuse); glMaterialfv(GL_FRONT,GL_SPECULAR,Specular); glMaterialf(GL_FRONT,GL_SHININESS,8); } glPushMatrix(); glTranslatef(pos[0], pos[1], pos[2]); glRotatef( anglex, 1.0f, 0.0f, 0.0f);//x軸回転 glutSolidTorus(0.2, 0.5, 10, 10); glPopMatrix(); } void drawFloor(float widthX, float widthZ, int nx, int nz){ int i, j; //Floor1枚当たりの幅 float wX = widthX / (float)nx; float wZ = widthZ / (float)nz; float diffuse[][4] = { { 0.9f, 0.9f, 0.9f, 1.0f}, { 0.1f, 0.1f, 0.1f, 1.0f} }; float ambient[] = { 0.2f, 0.2f, 0.2f, 1.0f}; float specular[]= { 0.5f, 0.5f, 0.5f, 1.0f}; glMaterialfv(GL_FRONT,GL_AMBIENT,ambient); glMaterialfv(GL_FRONT,GL_SPECULAR,specular); glMaterialf(GL_FRONT,GL_SHININESS,10); glNormal3d(0.0, 1.0, 0.0); glPushMatrix(); for (j = 0; j nz; j++) { float z1 = -widthZ / 2.0f + wZ * j; float z2 = z1 + wZ; for (i = 0; i nx; i++) { float x1 = -widthX / 2.0f + wX * i; float x2 = x1 + wX; glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse[(i + j) 1]); glBegin(GL_QUADS); glVertex3d(x1, 0.0, z1); glVertex3d(x1, 0.0, z2); glVertex3d(x2, 0.0, z2); glVertex3d(x2, 0.0, z1); glEnd(); } } glPopMatrix(); } void CalcShadowMat(float* mat){ float ex, ey, ez;//光源の方向 float s; //object中心から光源までの距離 float x, y, z; x = lightpos[0] - pos[0]; y = lightpos[1] - pos[1]; z = lightpos[2] - pos[2]; //光源の方向ベクトル s = sqrt(x * x + y * y + z * z); ex = x / s; ey = y / s; ez = z / s; //shadow matrix mat[0] = ey; mat[1] = 0.0f; mat[2] = 0.0f; mat[3] = 0.0f; mat[4] = -ex; mat[5] = 0.0f; mat[6] = -ez; mat[7] = 0.0f; mat[8] = 0.0f; mat[9] = 0.0f; mat[10] = ey; mat[11] = 0.0f; mat[12] = 0.0f; mat[13] = 0.001f * ey; mat[14] = 0.0f; mat[15] = ey; } void drawShadow(){ float mat[16]; glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glDepthMask(GL_FALSE); CalcShadowMat(mat); glPushMatrix(); glMultMatrixf(mat); draw(true); glPopMatrix(); glDepthMask(GL_TRUE); glDisable(GL_BLEND); } void display(void){ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport(0, 0, WIDTH, HEIGHT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); //視野角,アスペクト比(ウィンドウの幅/高さ),描画する範囲(最も近い距離,最も遠い距離) gluPerspective(30.0, (double)WIDTH / (double)HEIGHT, 1.0, 1000.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //視点の設定 gluLookAt(10.0,10.0,-2.0, //カメラの座標 0.0,0.0,0.0, // 注視点の座標 0.0,1.0,0.0); // 画面の上方向を指すベクトル //ライトの設定 setLight(); glsl.ON(); draw(false); drawFloor(10.0, 10.0, 10, 10); drawShadow(); glsl.OFF(); glutSwapBuffers(); } void idle(void){ anglex+=2.0f; if(flag){pos[2]+=0.001f;}else{pos[2]-=0.001f;} if(pos[2] 3.0f)flag=false; if(pos[2] -3.0f)flag=true; Sleep(1); glutPostRedisplay(); } void Init(){ glsl.InitGLSL( vertex.shader , flagment.shader ); glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_NORMALIZE); } void main(int argc, char *argv[]){ glutInitWindowPosition(100, 100); glutInitWindowSize(WIDTH, HEIGHT); glutInit( argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); glutCreateWindow( 簡易シャドウ ); glutDisplayFunc(display); glutIdleFunc(idle); Init(); glutMainLoop(); return; }
https://w.atwiki.jp/bambooflow/pages/317.html
QtでOpenGL:バージョンの確認 QtでOpenGL:バージョンの確認QGLForamtを使う glGetStringで確認 QGLForamtを使う Qt上で動作するOpenGLのバージョンを確認するには、 QGLFormat openGLVersionFlags を使います。 QGLFormat #include QtGui/QApplication #include QtGui/QMessageBox #include QtOpenGL/QGLFormat int main(int argc, char *argv[]) { QApplication a(argc, argv); if ((QGLFormat openGLVersionFlags() QGLFormat OpenGL_Version_1_5) == 0) { QMessageBox critical(0, "OpenGL features missing", "OpenGL version 1.5 or higher is required.\n" "The program will now exit."); return -1; } // nothing. return a.exec(); } glGetStringで確認 OpenGLの機能であるglGetStringを使います。 #include QDebug void GLWidget initializeGL() { qDebug() "OpenGL Ver. " (const char*)(glGetString(GL_VERSION)); qDebug() "Shader Ver. " (const char*)(glGetString(GL_SHADING_LANGUAGE_VERSION)); qDebug() "Vendor " (const char*)(glGetString(GL_VENDOR)); qDebug() "GPU " (const char*)(glGetString(GL_RENDERER)); } 例) OpenGL Ver. 3.3.0 Shader Ver. 3.30 NVIDIA via Cg compiler Vendor NVIDIA Corporation GPU GeForce GTX 260/PCI/SSE2 initializeGLで記述しているのは、コンストラクタで使おうとすると何も返ってこないからです。
https://w.atwiki.jp/keroro00innovator/pages/979.html
abnormalize abnormalize アーティスト 凛として時雨 発売日 2012年11月14日 レーベル SMAR デイリー最高順位 1位(2012年11月14日) 週間最高順位 1位(2012年11月20日) 月間最高順位 4位(2012年11月) 年間最高順位 50位(2012年) 初動売上 17219 累計売上 32779 週間1位 収録内容 曲名 タイアップ 視聴 1 abnormalize PSYCHO-PASS サイコパス OP 2 make up syndrome ランキング 週 月日 順位 変動 週/月間枚数 累計枚数 1 11/20 1 新 17219 17219 2 11/27 7 ↓ 4210 21429 3 12/4 10 ↓ 2437 23866 2012年11月 4 新 23866 23866 4 12/11 13 ↓ 1883 25749 5 12/18 14 ↓ 1237 26986 6 12/25 14 → 1263 28249 7 13/1/6 9 ↑ 1487 29736 2012年12月 16 ↓ 5870 29736 8 1/8 10 ↓ 1006 30742 9 1/15 17 ↓ 660 31402 10 1/22 ↓ 405 31807 11 1/29 426 32233 12 2/5 278 32511 2013年1月 44 ↓ 2775 32511 13 2/12 268 32779 PSYCHO-PASS サイコパス OP 前作 次作 abnormalize Out of ControlNothing s CarvedIn Stone 関連CD 名前のない怪物 Enigmatic Feeling unravel
https://w.atwiki.jp/opengl/pages/184.html
スポットライトです。 vertex.shader //フラグメントシェーダーに渡す変数 varying vec3 P;//位置ベクトル varying vec3 N;//法線ベクトル void main(void) { P = vec3(gl_ModelViewMatrix * gl_Vertex); N = normalize(gl_NormalMatrix * gl_Normal); gl_Position = ftransform(); } flagment.shader //頂点シェーダーから受け取る変数 varying vec3 P;//位置ベクトル varying vec3 N;//法線ベクトル int numLight = 2; void main(void) { gl_FragColor = vec4(0.0); float attenuation = 1.0; for(int i = 0; i numLight; i++){ vec3 L = gl_LightSource[i].position.xyz - P;//光源ベクトル if(gl_LightSource[i].spotCutoff == 180.0){//通常の光源 float d = length(L);//光源までの距離 //減衰計数 attenuation = 1.0 / (gl_LightSource[i].constantAttenuation + gl_LightSource[i].linearAttenuation * d + gl_LightSource[i].quadraticAttenuation * d * d ); } L = normalize(L); if(gl_LightSource[i].spotCutoff = 90.0){//スポットライト float LS = dot(- L, normalize(gl_LightSource[i].spotDirection)); if(LS gl_LightSource[i].spotCosCutoff) attenuation = 0.0;//スポットライトの外側 else attenuation = pow(LS, gl_LightSource[i].spotExponent); } N = normalize(N); vec4 ambient = gl_FrontLightProduct[i].ambient; float dotNL = dot(N, L); vec4 diffuse = gl_FrontLightProduct[i].diffuse * max(0.0, dotNL); vec3 V = normalize(-P); vec3 H = normalize(L + V); float powNH = pow(max(dot(N, H), 0.0), gl_FrontMaterial.shininess); if(dotNL = 0.0) powNH = 0.0; vec4 specular = gl_FrontLightProduct[i].specular * powNH; //統合 vec4 col = ambient + diffuse + specular; col *= attenuation; gl_FragColor += col; } } GLSL.h #pragma once #include stdio.h //GLSLクラス class GLSL{ public GLuint ShaderProg; GLuint VertexShader, FragmentShader; void ReadShaderCompile(GLuint Shader, const char *File);//shader fileを読み込みコンパイルする void Link( GLuint Prog );//リンクする void InitGLSL(const char *VertexFile);//GLSLの初期化 void InitGLSL(const char *VertexFile, const char *FragmentFile);//GLSLの初期化 void ON();//シェーダー描画に切り替え void OFF();//シェーダー解除 ~GLSL(); }; void GLSL ReadShaderCompile(GLuint Shader, const char *File){ FILE *fp; char *buf; GLsizei size, len; GLint compiled; fopen_s( fp,File, rb ); if(!fp) printf( ファイルを開くことができません %s\n , File); fseek(fp, 0, SEEK_END); size = ftell(fp); buf = (GLchar *)malloc(size); if (buf == NULL) { printf( メモリが確保できませんでした \n ); } fseek(fp, 0, SEEK_SET); fread(buf, 1, size, fp); glShaderSource(Shader, 1, (const GLchar **) buf, size); free(buf); fclose(fp); glCompileShader(Shader); glGetShaderiv( Shader, GL_COMPILE_STATUS, compiled ); if ( compiled == GL_FALSE ) { printf( コンパイルできませんでした!! %s \n , File); glGetProgramiv( Shader, GL_INFO_LOG_LENGTH, size ); if ( size 0 ) { buf = (char *)malloc(size); glGetShaderInfoLog( Shader, size, len, buf); printf(buf); free(buf); } } } void GLSL Link( GLuint Prog ){ GLsizei size, len; GLint linked; char *infoLog ; glLinkProgram( Prog ); glGetProgramiv( Prog, GL_LINK_STATUS, linked ); if ( linked == GL_FALSE ){ printf( リンクできませんでした!! \n ); glGetProgramiv( Prog, GL_INFO_LOG_LENGTH, size ); if ( size 0 ){ infoLog = (char *)malloc(size); glGetProgramInfoLog( Prog, size, len, infoLog ); printf(infoLog); free(infoLog); } } } void GLSL InitGLSL(const char *VertexFile){ GLenum err = glewInit(); if (err != GLEW_OK) { printf( Error %s\n , glewGetErrorString(err)); } printf( VENDOR= %s \n , glGetString(GL_VENDOR)); printf( GPU= %s \n , glGetString(GL_RENDERER)); printf( OpenGL= %s \n , glGetString(GL_VERSION)); printf( GLSL= %s \n , glGetString(GL_SHADING_LANGUAGE_VERSION)); VertexShader = glCreateShader(GL_VERTEX_SHADER); ReadShaderCompile(VertexShader, VertexFile); ShaderProg = glCreateProgram(); glAttachShader(ShaderProg, VertexShader); glDeleteShader(VertexShader); Link(ShaderProg); } void GLSL InitGLSL(const char *VertexFile, const char *FragmentFile){ GLenum err = glewInit(); if (err != GLEW_OK) { printf( Error %s\n , glewGetErrorString(err)); } printf( VENDOR= %s \n , glGetString(GL_VENDOR)); printf( GPU= %s \n , glGetString(GL_RENDERER)); printf( OpenGL= %s \n , glGetString(GL_VERSION)); printf( GLSL= %s \n , glGetString(GL_SHADING_LANGUAGE_VERSION)); VertexShader = glCreateShader(GL_VERTEX_SHADER); FragmentShader = glCreateShader(GL_FRAGMENT_SHADER); ReadShaderCompile(VertexShader, VertexFile); ReadShaderCompile(FragmentShader, FragmentFile); ShaderProg = glCreateProgram(); glAttachShader(ShaderProg, VertexShader); glAttachShader(ShaderProg, FragmentShader); glDeleteShader(VertexShader); glDeleteShader(FragmentShader); Link(ShaderProg); } void GLSL ON(){ glUseProgram(ShaderProg); } void GLSL OFF(){ glUseProgram(0); } GLSL ~GLSL(){ glDeleteProgram(ShaderProg); } main.cpp #pragma comment(linker, /SUBSYSTEM WINDOWS /ENTRY mainCRTStartup ) #pragma comment(lib, glew32.lib ) #include GL/glew.h #include GL/freeglut/freeglut.h #include GLSL.h #include math.h #define PAI 3.141592f #define WIDTH 640 #define HEIGHT 480 GLSL glsl; //回転用 float anglex = 0.0f; //ライトの位置 GLfloat lightpos[] = { 0.0, 4.0, 0.0, 1.0 }; float Ambient[] = {0.2f, 0.1f, 0.2f, 1.0f}; float Diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f}; float Specular[]= { 0.4f, 0.4f, 0.4f, 1.0f};//鏡面反射 float AmbientLight[] = { 1.0f, 1.0f, 1.0f, 1.0f}; float DiffuseLight[] = { 0.7f, 0.7f, 0.7f, 1.0f}; float SpecularLight[] = {1.0f, 1.0f, 1.0f, 1.0f};//鏡面光 float lightDiffuse[4] = {0.0, 1.0, 0.0, 1.0}; //拡散光 float lightSpecular[4] = {0.0, 1.0, 0.0, 1.0}; //鏡面光 float spotExp = 5.0; //LIGHT1 float spotCutoff = 25.0; //LIGHT1 float spotDir[3] ; //LIGHT1 float pos[] = {-0.7f, 2.0f, 0.0f};//位置 bool flag = true; float constAtt = 1.0; float linearAtt = 0.0; float quadraAtt = 0.0; //影のマテリアル float shadowDiffuse[] = {0.0f,0.0f,0.0f,0.3f};//影の拡散光 float shadowSpecular[] = {0.0f,0.0f,0.0f,1.0f};//影の鏡面光 void draw(bool flag){ if(flag) { glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,shadowDiffuse); glMaterialfv(GL_FRONT,GL_SPECULAR,shadowSpecular); }else{ glMaterialfv(GL_FRONT,GL_AMBIENT,Ambient); glMaterialfv(GL_FRONT,GL_DIFFUSE,Diffuse); glMaterialfv(GL_FRONT,GL_SPECULAR,Specular); glMaterialf(GL_FRONT,GL_SHININESS,8); } glPushMatrix(); glTranslatef(pos[0], pos[1], pos[2]); glRotatef( anglex, 1.0f, 0.0f, 0.0f);//x軸回転 glutSolidCube(1.0); glPopMatrix(); } void drawFloor(float widthX, float widthZ, int nx, int nz){ int i, j; //Floor1枚当たりの幅 float wX = widthX / (float)nx; float wZ = widthZ / (float)nz; float diffuse[][4] = { { 0.9f, 0.9f, 0.9f, 1.0f}, { 0.1f, 0.1f, 0.1f, 1.0f} }; float ambient[] = { 0.2f, 0.2f, 0.2f, 1.0f}; float specular[]= { 0.5f, 0.5f, 0.5f, 1.0f}; glMaterialfv(GL_FRONT,GL_AMBIENT,ambient); glMaterialfv(GL_FRONT,GL_SPECULAR,specular); glMaterialf(GL_FRONT,GL_SHININESS,10); glNormal3d(0.0, 1.0, 0.0); glPushMatrix(); for (j = 0; j nz; j++) { float z1 = -widthZ / 2.0f + wZ * j; float z2 = z1 + wZ; for (i = 0; i nx; i++) { float x1 = -widthX / 2.0f + wX * i; float x2 = x1 + wX; glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse[(i + j) 1]); glBegin(GL_QUADS); glVertex3d(x1, 0.0, z1); glVertex3d(x1, 0.0, z2); glVertex3d(x2, 0.0, z2); glVertex3d(x2, 0.0, z1); glEnd(); } } glPopMatrix(); } void CalcShadowMat(float* mat){ float ex, ey, ez;//光源の方向 float s; //object中心から光源までの距離 float x, y, z; x = lightpos[0] - pos[0]; y = lightpos[1] - pos[1]; z = lightpos[2] - pos[2]; //光源の方向ベクトル s = sqrt(x * x + y * y + z * z); ex = x / s; ey = y / s; ez = z / s; //shadow matrix mat[0] = ey; mat[1] = 0.0f; mat[2] = 0.0f; mat[3] = 0.0f; mat[4] = -ex; mat[5] = 0.0f; mat[6] = -ez; mat[7] = 0.0f; mat[8] = 0.0f; mat[9] = 0.0f; mat[10] = ey; mat[11] = 0.0f; mat[12] = 0.0f; mat[13] = 0.001f * ey; mat[14] = 0.0f; mat[15] = ey; } void drawShadow(){ float mat[16]; glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glDepthMask(GL_FALSE); CalcShadowMat( mat); glPushMatrix(); glMultMatrixf(mat); draw(true); glPopMatrix(); glDepthMask(GL_TRUE); glDisable(GL_BLEND); } void setLight(){ //LIGHT1 glLightfv(GL_LIGHT1, GL_DIFFUSE, lightDiffuse); glLightfv(GL_LIGHT1, GL_AMBIENT, lightDiffuse); glLightfv(GL_LIGHT1, GL_SPECULAR, lightSpecular); glLightfv(GL_LIGHT1, GL_POSITION, lightpos); //LIGHT1はスポットライト(スポットライトは常にワールド空間の原点を向く) for(int i = 0; i 3; i++) spotDir[i] = -lightpos[i]; glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, spotDir); glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, spotExp); glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, spotCutoff); glEnable(GL_LIGHTING); } void display(void){ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport(0, 0, WIDTH, HEIGHT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); //視野角,アスペクト比(ウィンドウの幅/高さ),描画する範囲(最も近い距離,最も遠い距離) gluPerspective(30.0, (double)WIDTH / (double)HEIGHT, 1.0, 1000.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //視点の設定 gluLookAt(10.0,10.0,-2.0, //カメラの座標 0.0,0.0,0.0, // 注視点の座標 0.0,1.0,0.0); // 画面の上方向を指すベクトル //ライトの設定 setLight(); glsl.ON(); draw(false); drawFloor(10.0, 10.0, 10, 10); drawShadow(); glsl.OFF(); glutSwapBuffers(); } void idle(void){ if(spotExp 50.0f)flag=false; if(spotExp 5.0f)flag=true; if(flag){spotExp+=0.5f;}else{spotExp-=0.5f;} anglex+=2.0f; Sleep(1); glutPostRedisplay(); } void Init(){ glsl.InitGLSL( vertex.shader , flagment.shader ); glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glEnable(GL_NORMALIZE); } void main(int argc, char *argv[]){ glutInitWindowPosition(100, 100); glutInitWindowSize(WIDTH, HEIGHT); glutInit( argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); glutCreateWindow( スポットライト ); glutDisplayFunc(display); glutIdleFunc(idle); Init(); glutMainLoop(); return; }
https://w.atwiki.jp/opengl/pages/44.html
環境光だけではのっぺりとした図にしかなりません。 立体的に見せるには陰影を付けてやらなければなりません。 拡散反射光は光源から入ってくる光を全ての方向に均一に反射します。 紙のようにざらざらとした光沢の少ないものの表現に適しています。 反射する光の量は、入射する光の量に応じて変化し、入射する光の量は 光のあたる場所によって異なるので、物体の形に陰が付きます。 左の画像は頂点シェーダーのみで陰影を付けたものですが、ハイライトの部分に何やら 線のようなものが見えます。これは頂点単位で色の補間が行われているためです。 右の画像は頂点シェーダーで位置ベクトルと法線ベクトルを計算しておき、フラグメントシェーダーに 渡してフラグメントシェーダーで光の計算をしています。 こうするとピクセル単位で色の計算(補間)が行われるので非常に綺麗な結果が得られます。 フラグメントシェーダーに渡す変数は varying で宣言し、頂点シェーダーとフラグメントシェーダーの 両方で同じ変数名で宣言しなければなりません。 今回は右の画像のプログラムを紹介しておきます。 vertex.shader //フラグメントシェーダーに渡す変数 varying vec3 P;//位置ベクトル varying vec3 N;//法線ベクトル void main(void) { P = vec3(gl_ModelViewMatrix * gl_Vertex); N = normalize(gl_NormalMatrix * gl_Normal); gl_Position = ftransform(); } flagment.shader //頂点シェーダーから受け取る変数 varying vec3 P;//位置ベクトル varying vec3 N;//法線ベクトル void main(void) { vec3 L = normalize(gl_LightSource[0].position.xyz - P); N = normalize(N); vec4 ambient = gl_FrontLightProduct[0].ambient; float dotNL = dot(N, L); vec4 diffuse = gl_FrontLightProduct[0].diffuse * max(0.0, dotNL); //統合 gl_FragColor = ambient + diffuse; } GLSL.h #pragma once #include stdio.h //GLSLクラス class GLSL{ public GLuint ShaderProg; GLuint VertexShader, FragmentShader; void ReadShaderCompile(GLuint Shader, const char *File);//shader fileを読み込みコンパイルする void Link( GLuint Prog );//リンクする void InitGLSL(const char *VertexFile);//GLSLの初期化 void InitGLSL(const char *VertexFile, const char *FragmentFile);//GLSLの初期化 void ON();//シェーダー描画に切り替え void OFF();//シェーダー解除 ~GLSL(); }; void GLSL ReadShaderCompile(GLuint Shader, const char *File){ FILE *fp; char *buf; GLsizei size, len; GLint compiled; fopen_s( fp,File, rb ); if(!fp) printf( ファイルを開くことができません %s\n , File); fseek(fp, 0, SEEK_END); size = ftell(fp); buf = (GLchar *)malloc(size); if (buf == NULL) { printf( メモリが確保できませんでした \n ); } fseek(fp, 0, SEEK_SET); fread(buf, 1, size, fp); glShaderSource(Shader, 1, (const GLchar **) buf, size); free(buf); fclose(fp); glCompileShader(Shader); glGetShaderiv( Shader, GL_COMPILE_STATUS, compiled ); if ( compiled == GL_FALSE ) { printf( コンパイルできませんでした!! %s \n , File); glGetProgramiv( Shader, GL_INFO_LOG_LENGTH, size ); if ( size 0 ) { buf = (char *)malloc(size); glGetShaderInfoLog( Shader, size, len, buf); printf(buf); free(buf); } } } void GLSL Link( GLuint Prog ){ GLsizei size, len; GLint linked; char *infoLog ; glLinkProgram( Prog ); glGetProgramiv( Prog, GL_LINK_STATUS, linked ); if ( linked == GL_FALSE ){ printf( リンクできませんでした!! \n ); glGetProgramiv( Prog, GL_INFO_LOG_LENGTH, size ); if ( size 0 ){ infoLog = (char *)malloc(size); glGetProgramInfoLog( Prog, size, len, infoLog ); printf(infoLog); free(infoLog); } } } void GLSL InitGLSL(const char *VertexFile){ GLenum err = glewInit(); if (err != GLEW_OK) { printf( Error %s\n , glewGetErrorString(err)); } printf( VENDOR= %s \n , glGetString(GL_VENDOR)); printf( GPU= %s \n , glGetString(GL_RENDERER)); printf( OpenGL= %s \n , glGetString(GL_VERSION)); printf( GLSL= %s \n , glGetString(GL_SHADING_LANGUAGE_VERSION)); VertexShader = glCreateShader(GL_VERTEX_SHADER); ReadShaderCompile(VertexShader, VertexFile); ShaderProg = glCreateProgram(); glAttachShader(ShaderProg, VertexShader); glDeleteShader(VertexShader); Link(ShaderProg); } void GLSL InitGLSL(const char *VertexFile, const char *FragmentFile){ GLenum err = glewInit(); if (err != GLEW_OK) { printf( Error %s\n , glewGetErrorString(err)); } printf( VENDOR= %s \n , glGetString(GL_VENDOR)); printf( GPU= %s \n , glGetString(GL_RENDERER)); printf( OpenGL= %s \n , glGetString(GL_VERSION)); printf( GLSL= %s \n , glGetString(GL_SHADING_LANGUAGE_VERSION)); VertexShader = glCreateShader(GL_VERTEX_SHADER); FragmentShader = glCreateShader(GL_FRAGMENT_SHADER); ReadShaderCompile(VertexShader, VertexFile); ReadShaderCompile(FragmentShader, FragmentFile); ShaderProg = glCreateProgram(); glAttachShader(ShaderProg, VertexShader); glAttachShader(ShaderProg, FragmentShader); glDeleteShader(VertexShader); glDeleteShader(FragmentShader); Link(ShaderProg); } void GLSL ON(){ glUseProgram(ShaderProg); } void GLSL OFF(){ glUseProgram(0); } GLSL ~GLSL(){ glDeleteProgram(ShaderProg); } main.cpp #pragma comment(linker, /SUBSYSTEM WINDOWS /ENTRY mainCRTStartup ) #pragma comment(lib, glew32.lib ) #include stdio.h #include GL/glew.h #include GL/freeglut/freeglut.h #include GLSL.h #define WIDTH 320 #define HEIGHT 240 GLSL glsl; //回転用 float anglex = 0.0f; //ライトの位置 GLfloat lightpos[] = { 20.0, 80.0, -50.0, 1.0 }; float Ambient[] = {0.8f, 0.0f, 0.2f, 1.0f}; float Diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f};//拡散反射 float AmbientLight[] = { 1.0f, 1.0f, 1.0f, 1.0f}; float DiffuseLight[] = { 0.2f, 0.7f, 0.7f, 1.0f};//拡散光 void setLight(){ glMaterialfv(GL_FRONT,GL_AMBIENT,Ambient); glMaterialfv(GL_FRONT,GL_DIFFUSE,Diffuse); glLightfv(GL_LIGHT0, GL_AMBIENT, AmbientLight); glLightfv(GL_LIGHT0, GL_DIFFUSE, DiffuseLight); glLightfv(GL_LIGHT0, GL_POSITION, lightpos); } void display(void){ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport(0, 0, WIDTH, HEIGHT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); //視野角,アスペクト比(ウィンドウの幅/高さ),描画する範囲(最も近い距離,最も遠い距離) gluPerspective(30.0, (double)WIDTH / (double)HEIGHT, 1.0, 1000.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //視点の設定 gluLookAt(150.0,100.0,-200.0, //カメラの座標 0.0,0.0,0.0, // 注視点の座標 0.0,1.0,0.0); // 画面の上方向を指すベクトル //ライトの設定 setLight(); //回転 glRotatef(anglex,1.0f,0.0f,0.0f);//X軸を回転 glsl.ON();//シェーダー描画に切り替え glutSolidSphere(40.0,16,16); glsl.OFF();//シェーダー解除 glutSwapBuffers(); } void idle(void){ anglex+=2.0f; Sleep(1); glutPostRedisplay(); } void Init(){ glsl.InitGLSL( vertex.shader , flagment.shader ); glClearColor(0.3f, 0.3f, 0.3f, 1.0f); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); } void main(int argc, char *argv[]){ glutInitWindowPosition(100, 100); glutInitWindowSize(WIDTH, HEIGHT); glutInit( argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); glutCreateWindow( ディフューズ ); glutDisplayFunc(display); glutIdleFunc(idle); Init(); glutMainLoop(); return; }
https://w.atwiki.jp/opengl/pages/183.html
距離による光の減衰です。 vertex.shader //フラグメントシェーダーに渡す変数 varying vec3 P;//位置ベクトル varying vec3 N;//法線ベクトル void main(void) { P = vec3(gl_ModelViewMatrix * gl_Vertex); N = normalize(gl_NormalMatrix * gl_Normal); gl_Position = ftransform(); } flagment.shader //頂点シェーダーから受け取る変数 varying vec3 P;//位置ベクトル varying vec3 N;//法線ベクトル void main(void) { vec3 L = gl_LightSource[0].position.xyz - P; float d = length(L);//光源までの距離 //減衰計数 float attenuation = 1.0 / (gl_LightSource[0].constantAttenuation + gl_LightSource[0].linearAttenuation * d + gl_LightSource[0].quadraticAttenuation * d * d ); L = normalize(L); N = normalize(N); vec4 ambient = gl_FrontLightProduct[0].ambient; float dotNL = dot(N, L); vec4 diffuse = gl_FrontLightProduct[0].diffuse * max(0.0, dotNL); vec3 V = normalize(-P); vec3 H = normalize(L + V); float powNH = pow(max(dot(N, H), 0.0), gl_FrontMaterial.shininess); if(dotNL = 0.0) powNH = 0.0; vec4 specular = gl_FrontLightProduct[0].specular * powNH; //統合 gl_FragColor = ambient + diffuse + specular; //減衰率を乗じる gl_FragColor *= attenuation; } GLSL.h #pragma once #include stdio.h //GLSLクラス class GLSL{ public GLuint ShaderProg; GLuint VertexShader, FragmentShader; void ReadShaderCompile(GLuint Shader, const char *File);//shader fileを読み込みコンパイルする void Link( GLuint Prog );//リンクする void InitGLSL(const char *VertexFile);//GLSLの初期化 void InitGLSL(const char *VertexFile, const char *FragmentFile);//GLSLの初期化 void ON();//シェーダー描画に切り替え void OFF();//シェーダー解除 ~GLSL(); }; void GLSL ReadShaderCompile(GLuint Shader, const char *File){ FILE *fp; char *buf; GLsizei size, len; GLint compiled; fopen_s( fp,File, rb ); if(!fp) printf( ファイルを開くことができません %s\n , File); fseek(fp, 0, SEEK_END); size = ftell(fp); buf = (GLchar *)malloc(size); if (buf == NULL) { printf( メモリが確保できませんでした \n ); } fseek(fp, 0, SEEK_SET); fread(buf, 1, size, fp); glShaderSource(Shader, 1, (const GLchar **) buf, size); free(buf); fclose(fp); glCompileShader(Shader); glGetShaderiv( Shader, GL_COMPILE_STATUS, compiled ); if ( compiled == GL_FALSE ) { printf( コンパイルできませんでした!! %s \n , File); glGetProgramiv( Shader, GL_INFO_LOG_LENGTH, size ); if ( size 0 ) { buf = (char *)malloc(size); glGetShaderInfoLog( Shader, size, len, buf); printf(buf); free(buf); } } } void GLSL Link( GLuint Prog ){ GLsizei size, len; GLint linked; char *infoLog ; glLinkProgram( Prog ); glGetProgramiv( Prog, GL_LINK_STATUS, linked ); if ( linked == GL_FALSE ){ printf( リンクできませんでした!! \n ); glGetProgramiv( Prog, GL_INFO_LOG_LENGTH, size ); if ( size 0 ){ infoLog = (char *)malloc(size); glGetProgramInfoLog( Prog, size, len, infoLog ); printf(infoLog); free(infoLog); } } } void GLSL InitGLSL(const char *VertexFile){ GLenum err = glewInit(); if (err != GLEW_OK) { printf( Error %s\n , glewGetErrorString(err)); } printf( VENDOR= %s \n , glGetString(GL_VENDOR)); printf( GPU= %s \n , glGetString(GL_RENDERER)); printf( OpenGL= %s \n , glGetString(GL_VERSION)); printf( GLSL= %s \n , glGetString(GL_SHADING_LANGUAGE_VERSION)); VertexShader = glCreateShader(GL_VERTEX_SHADER); ReadShaderCompile(VertexShader, VertexFile); ShaderProg = glCreateProgram(); glAttachShader(ShaderProg, VertexShader); glDeleteShader(VertexShader); Link(ShaderProg); } void GLSL InitGLSL(const char *VertexFile, const char *FragmentFile){ GLenum err = glewInit(); if (err != GLEW_OK) { printf( Error %s\n , glewGetErrorString(err)); } printf( VENDOR= %s \n , glGetString(GL_VENDOR)); printf( GPU= %s \n , glGetString(GL_RENDERER)); printf( OpenGL= %s \n , glGetString(GL_VERSION)); printf( GLSL= %s \n , glGetString(GL_SHADING_LANGUAGE_VERSION)); VertexShader = glCreateShader(GL_VERTEX_SHADER); FragmentShader = glCreateShader(GL_FRAGMENT_SHADER); ReadShaderCompile(VertexShader, VertexFile); ReadShaderCompile(FragmentShader, FragmentFile); ShaderProg = glCreateProgram(); glAttachShader(ShaderProg, VertexShader); glAttachShader(ShaderProg, FragmentShader); glDeleteShader(VertexShader); glDeleteShader(FragmentShader); Link(ShaderProg); } void GLSL ON(){ glUseProgram(ShaderProg); } void GLSL OFF(){ glUseProgram(0); } GLSL ~GLSL(){ glDeleteProgram(ShaderProg); } main.cpp #pragma comment(linker, /SUBSYSTEM WINDOWS /ENTRY mainCRTStartup ) #pragma comment(lib, glew32.lib ) #include GL/glew.h #include GL/freeglut/freeglut.h #include GLSL.h #include math.h #define PAI 3.141592f #define WIDTH 640 #define HEIGHT 480 GLSL glsl; //回転用 float anglex = 0.0f; //ライトの位置 GLfloat lightpos[] = { 0.0, 4.0, 0.0, 1.0 }; float Ambient[] = {0.2f, 0.1f, 0.2f, 1.0f}; float Diffuse[] = {0.8f, 0.0f, 0.0f, 1.0f}; float Specular[]= { 0.4f, 0.4f, 0.4f, 1.0f};//鏡面反射 float AmbientLight[] = { 1.0f, 1.0f, 1.0f, 1.0f}; float DiffuseLight[] = { 0.7f, 0.7f, 0.7f, 1.0f}; float SpecularLight[] = {1.0f, 1.0f, 1.0f, 1.0f};//鏡面光 float pos[] = {-0.7f, 2.0f, 0.0f};//位置 float constAtt = 1.0; float linearAtt = 0.0; float quadraAtt = 0.0; //影のマテリアル float shadowDiffuse[] = {0.0f,0.0f,0.0f,0.3f};//影の拡散光 float shadowSpecular[] = {0.0f,0.0f,0.0f,1.0f};//影の鏡面光 void draw(bool flag){ if(flag) { glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,shadowDiffuse); glMaterialfv(GL_FRONT,GL_SPECULAR,shadowSpecular); }else{ glMaterialfv(GL_FRONT,GL_AMBIENT,Ambient); glMaterialfv(GL_FRONT,GL_DIFFUSE,Diffuse); glMaterialfv(GL_FRONT,GL_SPECULAR,Specular); glMaterialf(GL_FRONT,GL_SHININESS,8); } glPushMatrix(); glTranslatef(pos[0], pos[1], pos[2]); glRotatef( anglex, 1.0f, 0.0f, 0.0f);//x軸回転 glutSolidCube(1.0); glPopMatrix(); } void drawFloor(float widthX, float widthZ, int nx, int nz){ int i, j; //Floor1枚当たりの幅 float wX = widthX / (float)nx; float wZ = widthZ / (float)nz; float diffuse[][4] = { { 0.9f, 0.9f, 0.9f, 1.0f}, { 0.1f, 0.1f, 0.1f, 1.0f} }; float ambient[] = { 0.2f, 0.2f, 0.2f, 1.0f}; float specular[]= { 0.5f, 0.5f, 0.5f, 1.0f}; glMaterialfv(GL_FRONT,GL_AMBIENT,ambient); glMaterialfv(GL_FRONT,GL_SPECULAR,specular); glMaterialf(GL_FRONT,GL_SHININESS,10); glNormal3d(0.0, 1.0, 0.0); glPushMatrix(); for (j = 0; j nz; j++) { float z1 = -widthZ / 2.0f + wZ * j; float z2 = z1 + wZ; for (i = 0; i nx; i++) { float x1 = -widthX / 2.0f + wX * i; float x2 = x1 + wX; glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse[(i + j) 1]); glBegin(GL_QUADS); glVertex3d(x1, 0.0, z1); glVertex3d(x1, 0.0, z2); glVertex3d(x2, 0.0, z2); glVertex3d(x2, 0.0, z1); glEnd(); } } glPopMatrix(); } void CalcShadowMat(float* mat){ float ex, ey, ez;//光源の方向 float s; //object中心から光源までの距離 float x, y, z; x = lightpos[0] - pos[0]; y = lightpos[1] - pos[1]; z = lightpos[2] - pos[2]; //光源の方向ベクトル s = sqrt(x * x + y * y + z * z); ex = x / s; ey = y / s; ez = z / s; //shadow matrix mat[0] = ey; mat[1] = 0.0f; mat[2] = 0.0f; mat[3] = 0.0f; mat[4] = -ex; mat[5] = 0.0f; mat[6] = -ez; mat[7] = 0.0f; mat[8] = 0.0f; mat[9] = 0.0f; mat[10] = ey; mat[11] = 0.0f; mat[12] = 0.0f; mat[13] = 0.001f * ey; mat[14] = 0.0f; mat[15] = ey; } void drawShadow(){ float mat[16]; glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glDepthMask(GL_FALSE); CalcShadowMat( mat); glPushMatrix(); glMultMatrixf(mat); draw(true); glPopMatrix(); glDepthMask(GL_TRUE); glDisable(GL_BLEND); } void setLight(){ float lightAmbient0[] = {0.5, 0.5, 0.5, 1.0}; //環境光 float lightDiffuse0[] = {1.0, 1.0, 1.0, 1.0}; //拡散光 float lightSpecular0[] = {1.0, 1.0, 1.0, 1.0};//鏡面光 glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient0); glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse0); glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpecular0); glLightfv(GL_LIGHT0, GL_POSITION, lightpos); constAtt = 0.0f; linearAtt = 0.0f; quadraAtt = 1.0f / (lightpos[1] * lightpos[1]); glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, constAtt); glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, linearAtt); glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, quadraAtt); glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); } void drawLight(void){ glDisable(GL_LIGHTING); glColor3f(0.8f, 0.8f, 0.0f); glPushMatrix(); glTranslatef(lightpos[0], lightpos[1], lightpos[2]); glutSolidSphere(0.1f, 10, 10); glPopMatrix(); glEnable(GL_LIGHTING); } void display(void){ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport(0, 0, WIDTH, HEIGHT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); //視野角,アスペクト比(ウィンドウの幅/高さ),描画する範囲(最も近い距離,最も遠い距離) gluPerspective(30.0, (double)WIDTH / (double)HEIGHT, 1.0, 1000.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //視点の設定 gluLookAt(10.0,10.0,-2.0, //カメラの座標 0.0,0.0,0.0, // 注視点の座標 0.0,1.0,0.0); // 画面の上方向を指すベクトル //ライトの設定 setLight(); drawLight(); glsl.ON(); draw(false); drawFloor(10.0, 10.0, 10, 10); drawShadow(); glsl.OFF(); glutSwapBuffers(); } void idle(void){ anglex+=2.0f; Sleep(1); glutPostRedisplay(); } void Init(){ glsl.InitGLSL( vertex.shader , flagment.shader ); glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_NORMALIZE); } void main(int argc, char *argv[]){ glutInitWindowPosition(100, 100); glutInitWindowSize(WIDTH, HEIGHT); glutInit( argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); glutCreateWindow( 距離減衰 ); glutDisplayFunc(display); glutIdleFunc(idle); Init(); glutMainLoop(); return; }